const { newEnforcer, newModelFromString } = require("casbin");
const { BasicAdapter } = require("casbin-basic-adapter");

let cachedEnforcer;
let casbinDB;
/* 调用方式
(await global.e.enforce("admin", "/article", "POST")) === true
*/
const InitCasbin = async (dataBase) => {
  if (!cachedEnforcer) {
    casbinDB = dataBase;

    // 创建 Mongoose 适配器
    const adapter = await BasicAdapter.newAdapter("mysql2", casbinDB);

    // Casbin 模型字符串
    const modelText = `
        [request_definition]
        r = sub, obj, act
    
        [policy_definition]
        p = sub, obj, act
    
        [role_definition]
        g = _, _
    
        [policy_effect]
        e = some(where (p.eft == allow))
    
        [matchers]
        m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
        `;

    // 从字符串中加载 Casbin 模型
    const model = newModelFromString(modelText);

    // 初始化 Casbin Enforcer
    cachedEnforcer = await newEnforcer(model, adapter);

    // 设置 Casbin 的一些参数
    cachedEnforcer.enableAutoSave(true); //自动保存

    // 加载 Casbin 策略
    await cachedEnforcer.loadPolicy();
    console.log("Casbin 初始化成功");
  }

  return cachedEnforcer;
};

const LoadPolicy = async () => {
  await cachedEnforcer.loadPolicy();
};

const DeletePermissionForRole = async (rolelabel, ...permission) => {
  try {
    await global.e.deletePermissionForUser(rolelabel, ...permission);
    await LoadPolicy(); // 调用记载策略函数
  } catch (error) {
    console.log("DeletePermissionForRole失败", error);
  }
};

const DeletePermissionsForRole = async (rolelabel) => {
  try {
    await global.e.deletePermissionsForUser(rolelabel);
    await LoadPolicy(); // 调用记载策略函数
  } catch (error) {
    console.log("DeletePermissionForRole失败", error);
  }
};

const AddPermissionForRole = async (rolelabel, ...permission) => {
  const [url, method] = permission;
  try {
    await global.e.addPermissionForUser(rolelabel, url, method);
    LoadPolicy(); // 调用记载策略函数
  } catch (error) {
    console.log("AddPermissionForRole失败");
  }
};

const UpdatePolicy = async (oldV, newV) => {
  //更新API权限
  try {
    await global.e.updatePolicy(oldV, newV);
    LoadPolicy();
  } catch (error) {
    console.log("UpdatePolicy错误", error);
  }
};

const DeletePermission = async (...permission) => {
  try {
    await global.e.deletePermission(...permission);
    await LoadPolicy();
  } catch (error) {
    console.log("DeletePermission失败", error);
  }
};

const AddRoleForUser = async (user, role) => {
  try {
    await global.e.addRoleForUser(user, role);
    await LoadPolicy();
  } catch (error) {
    console.log("AddRoleForUser", error);
  }
};

const UpdateRoleLabels = async () => {
  try {
  } catch (error) {
    console.log("UpdateRoleLabels", error);
  }
};
// 批量添加 Policy
const AddPolicies = async (rules) => {
  try {
    if (rules.length === 0) return;
    await global.e.addPolicies(rules);
    await LoadPolicy();
  } catch (error) {
    console.log("AddPolicies失败", error);
  }
};

// 批量删除 API 权限: 根据角色名
const BatchDeletePermissions = async (roleLabels) => {
  try {
    //循环角色标签删除对应权限
    for (let rolelbael of roleLabels) {
      await global.e.deleteRoleForUser(rolelbael.label, "anonymous");
      await global.e.deleteRoleForUser(rolelbael.label, "logout");
      await global.e.deletePermissionsForUser(rolelbael.label);
    }
  } catch (error) {
    console.log("BatchDeletePermissions失败", error);
  }
};

module.exports = {
  InitCasbin,
  LoadPolicy,
  DeletePermissionForRole,
  AddPermissionForRole,
  UpdatePolicy,
  DeletePermission,
  AddRoleForUser,
  UpdateRoleLabels,
  AddPolicies,
  DeletePermissionsForRole,
  BatchDeletePermissions,
};
